# -*-coding: UTF-8 -*-

from Tkinter import *
from FrogLabModel import *
import random

try:
    from wPIL import Image, ImageTk, ImageOps
except ImportError:
    try:
        from PIL import Image, ImageTk, ImageOps
    except ImportError:
        import sys
        import tkMessageBox
        tkMessageBox.showwarning("Erreur", "S.V.P. Installez PIL pour jouer sur ce syst�me d'exploitation")
        sys.exit()

class Img():
    def __init__(self,argv,pos=Point(-1000,-1000)):
        self.pos = pos
        self.nom = argv["nom"]
        self.canvas=argv["canvas"]
        self.enlever=False
        if not argv["img"]:
            img = Image.open(argv["path"])
            img = img.resize((argv["largeur"],argv["hauteur"]),Image.ANTIALIAS)
        self.img = ImageTk.PhotoImage(img)
        self.item = self.canvas.create_image(pos.x,pos.y,image=self.img)

    def bouger(self,pos):
        self.pos = pos
        self.canvas.coords(self.item,self.pos.x,self.pos.y)

    def cacher(self):
        self.bouger(Point(-1000,-1000))

class Canevas():
    def __init__(self,canvas):
        self.canvas=canvas
        self.imgVisibles=[]
        self.imgInutilisees={}
        self.imgInfos={}
        self.texteVisible={}

    def ajouterImageInfos(self,nom,path,largeur,hauteur):
        self.imgInfos[nom] = {
            "nom":nom,
            "canvas":self.canvas,
            "path":path,
            "largeur":largeur,
            "hauteur":hauteur,
            "img":None
        }
        self.imgInutilisees[nom] = []

    def ajouterTexte(self,nom,valeur):
        self.texteVisible[nom] = self.canvas.create_text(-1000,-1000,fill="#333",text=valeur)

    # Prend en parametre un tableau : [ ["nom-image" : Point(x,y)], [..], [..] ]
    def update(self,images,textes):
        # On commence par afficher tout le texte
        for txt in textes:
            nom=txt[0]
            pos=txt[1]
            self.canvas.coords(self.texteVisible[nom],pos.x,pos.y)

        # On marque toutes les images comme etant a enlever:
        for img in self.imgVisibles:
            img.enlever=True

        # Pour chaque image de la liste recue, on verifie si une image est deja sur le canevas.
        for item in images:
            nom,pos = item[0],item[1]
            image=None
            trouve=False
            for img in self.imgVisibles:
                if img.nom==nom and img.enlever==True:
                    image=img
                    trouve=True
                    break
            if not trouve:
                if len(self.imgInutilisees[nom]) != 0:
                    image = self.imgInutilisees[nom].pop()
                else:
                    image = Img(self.imgInfos[nom])
                self.imgVisibles.append(image)
            image.enlever=False
            image.bouger(pos)

        # On enlever des images visibles toutes les images qui n'etait pas dans la liste recue.
        for img in self.imgVisibles:
            if img.enlever==True:
                img.cacher()
                self.imgInutilisees[img.nom].append(img)
                self.imgVisibles.remove(img)

class FrogLabVue():
    def __init__(self,root,w=800,h=600):
        self.w=w
        self.h=h
        self.root=root
        self.frame=Frame(root)
        self.frame.pack()
        self.canvas=Canvas(self.frame, width=self.w, height=self.h, background="#ccc")
        self.canvas.pack()
        self.controleur=None
        self.labyrintheDessine=False
        self.timerDessiner=False
        self.largeurCases=None
        self.bordures=None
        self.tempsRestant=0
        self.timer=None
        
        self.imgJoueur=[]
        self.itemJoueur={}
        self.anciennesDirections={}

        self.imBiere=None
        self.imSurprise=None
        self.imSurprises=[]

        self.imagesChargees=False
        self.cvs = Canevas(self.canvas)
        #self.canvas.focus_set()
       
        #self.root.bind("<Button-1>", lambda x: self.canvas.focus_set())
        self.root.bind('<Up>', self.depHaut)
        self.root.bind('<Down>', self.depBas)
        self.root.bind('<Left>', self.depGauche)
        self.root.bind('<Right>', self.depDroite)
        self.root.bind('<Control_L>', self.activerSurprise)
        
    def setControleur(self,c):
        self.controleur=c
        
    def setBindings(self):
        pass
        
    def setTimer(self, time, function):
        self.root.after(time, function)

    def depHaut(self,ev):
        self.controleur.deplacementHaut()

    def depBas(self,ev):
        self.controleur.deplacementBas()

    def depGauche(self,ev):
        self.controleur.deplacementGauche()

    def depDroite(self,ev):
        self.controleur.deplacementDroite()

    def activerSurprise(self,ev):
        print "========"
        self.controleur.activerSurprise()
        
    def dessinerLabyrinthe(self):
        if self.labyrintheDessine==True:
            return
        self.labyrintheDessine=True

        BORDURE = 20
        NB_CASE_W = self.controleur.getLargeurLabyrinthe()
        NB_CASE_H = self.controleur.getHauteurLabyrinthe()

        if NB_CASE_W > NB_CASE_H:
            LAB_W = self.w - 2 * BORDURE
            CASE_SZ = LAB_W / NB_CASE_W
            LAB_H = CASE_SZ * NB_CASE_H
            OX = BORDURE
            OY = (self.h - NB_CASE_H*CASE_SZ) / 2
        else:
            LAB_H = self.h - 2*BORDURE
            CASE_SZ = LAB_H / NB_CASE_H
            LAB_W = CASE_SZ * NB_CASE_W
            OY = BORDURE
            OX = (self.w - NB_CASE_W*CASE_SZ) / 2

        self.largeurCases = CASE_SZ
        self.ox = OX
        self.oy = OY

        # Redimensionner les images.
        imNord = Image.open('MiniJeux/FrogLab/images/nord.png')
        imNord = imNord.resize((CASE_SZ-6,7))
        self.imgNord = ImageTk.PhotoImage(imNord)

        imSud = Image.open('MiniJeux/FrogLab/images/sud.png')
        imSud = imSud.resize((CASE_SZ-6,7))
        self.imgSud = ImageTk.PhotoImage(imSud)

        imEst = Image.open('MiniJeux/FrogLab/images/est.png')
        imEst = imEst.resize((7,CASE_SZ-6))
        self.imgEst = ImageTk.PhotoImage(imEst)

        imOuest = Image.open('MiniJeux/FrogLab/images/ouest.png')
        imOuest = imOuest.resize((7,CASE_SZ-6))
        self.imgOuest = ImageTk.PhotoImage(imOuest)

        self.imgCentre = ImageTk.PhotoImage(Image.open('MiniJeux/FrogLab/images/centre.png'))

        # Dessiner les carres entre les murs.
        for i in range(NB_CASE_W+1):
            for j in range(NB_CASE_H+1):
                self.canvas.create_image(OX+CASE_SZ*i, OY+CASE_SZ*j, image=self.imgCentre)

        # Dessiner les murs.
        for i in range(NB_CASE_W):
            for j in range(NB_CASE_H):
                rangee = j
                rangeePhysique = NB_CASE_H-j-1

                if self.controleur.murNord(i,rangee):
                    self.canvas.create_image(OX+CASE_SZ*i+3, OY+CASE_SZ*rangeePhysique, image=self.imgNord,anchor=NW)

                if self.controleur.murSud(i,rangee):
                    self.canvas.create_image(OX+CASE_SZ*i+3, OY+CASE_SZ*rangeePhysique+CASE_SZ, image=self.imgSud,anchor=SW)

                if self.controleur.murEst(i,rangee):
                    self.canvas.create_image(OX+CASE_SZ*i+CASE_SZ, OY+CASE_SZ*rangeePhysique+3, image=self.imgEst,anchor=NE)

                if self.controleur.murOuest(i,rangee):
                    self.canvas.create_image(OX+CASE_SZ*i, OY+CASE_SZ*rangeePhysique+3, image=self.imgOuest,anchor=NW)
                
        # Dessiner les murs de contours.
        for i in range(NB_CASE_W):
            self.canvas.create_image(OX+CASE_SZ*i+3, OY, image=self.imgSud,anchor=SW)
            self.canvas.create_image(OX+CASE_SZ*i+3, OY+CASE_SZ*NB_CASE_H, image=self.imgNord,anchor=NW)

        for j in range(NB_CASE_H):
            self.canvas.create_image(OX, OY+CASE_SZ*j+3, image=self.imgEst,anchor=NE)
            self.canvas.create_image(OX+CASE_SZ*NB_CASE_W, OY+CASE_SZ*j+3, image=self.imgOuest,anchor=NW)

    def dessinerTimer(self):
        if not self.timer:
            self.timer = self.canvas.create_text(self.w/2,self.h/2,fill="#999",text="-",font=("default",167))
     
        tempsRestant = self.controleur.getTempsRestant()
        if tempsRestant != self.tempsRestant:
            self.canvas.itemconfig(self.timer, text=str(tempsRestant))
            self.tempsRestant = tempsRestant

    def chargerImagesElems(self,joueurs):
        sz=int(self.largeurCases*0.75)

        self.cvs.ajouterImageInfos("biere","MiniJeux/FrogLab/images/beer1.png",sz,sz)

        self.cvs.ajouterImageInfos("vert-0","MiniJeux/FrogLab/images/grenouille-verte-n.png",sz,sz)
        self.cvs.ajouterImageInfos("vert-1","MiniJeux/FrogLab/images/grenouille-verte-s.png",sz,sz)
        self.cvs.ajouterImageInfos("vert-2","MiniJeux/FrogLab/images/grenouille-verte-e.png",sz,sz)
        self.cvs.ajouterImageInfos("vert-3","MiniJeux/FrogLab/images/grenouille-verte-o.png",sz,sz)

        self.cvs.ajouterImageInfos("bleu-0","MiniJeux/FrogLab/images/grenouille-bleue-n.png",sz,sz)
        self.cvs.ajouterImageInfos("bleu-1","MiniJeux/FrogLab/images/grenouille-bleue-s.png",sz,sz)
        self.cvs.ajouterImageInfos("bleu-2","MiniJeux/FrogLab/images/grenouille-bleue-e.png",sz,sz)
        self.cvs.ajouterImageInfos("bleu-3","MiniJeux/FrogLab/images/grenouille-bleue-o.png",sz,sz)

        self.cvs.ajouterImageInfos("rouge-0","MiniJeux/FrogLab/images/grenouille-rouge-n.png",sz,sz)
        self.cvs.ajouterImageInfos("rouge-1","MiniJeux/FrogLab/images/grenouille-rouge-s.png",sz,sz)
        self.cvs.ajouterImageInfos("rouge-2","MiniJeux/FrogLab/images/grenouille-rouge-e.png",sz,sz)
        self.cvs.ajouterImageInfos("rouge-3","MiniJeux/FrogLab/images/grenouille-rouge-o.png",sz,sz)

        self.cvs.ajouterImageInfos("jaune-0","MiniJeux/FrogLab/images/grenouille-jaune-n.png",sz,sz)
        self.cvs.ajouterImageInfos("jaune-1","MiniJeux/FrogLab/images/grenouille-jaune-s.png",sz,sz)
        self.cvs.ajouterImageInfos("jaune-2","MiniJeux/FrogLab/images/grenouille-jaune-e.png",sz,sz)
        self.cvs.ajouterImageInfos("jaune-3","MiniJeux/FrogLab/images/grenouille-jaune-o.png",sz,sz)

        self.cvs.ajouterImageInfos("gris-0","MiniJeux/FrogLab/images/grenouille-grise-n.png",sz,sz)
        self.cvs.ajouterImageInfos("gris-1","MiniJeux/FrogLab/images/grenouille-grise-s.png",sz,sz)
        self.cvs.ajouterImageInfos("gris-2","MiniJeux/FrogLab/images/grenouille-grise-e.png",sz,sz)
        self.cvs.ajouterImageInfos("gris-3","MiniJeux/FrogLab/images/grenouille-grise-o.png",sz,sz)

        self.cvs.ajouterImageInfos("deplacer","MiniJeux/FrogLab/images/deplacer-biere.png",sz,sz)
        self.cvs.ajouterImageInfos("interchanger","MiniJeux/FrogLab/images/cycle.png",sz,sz)
        self.cvs.ajouterImageInfos("geler","MiniJeux/FrogLab/images/glacon2.png",sz,sz)
        self.cvs.ajouterImageInfos("teleporter","MiniJeux/FrogLab/images/trounoir.png",sz,sz)
        self.cvs.ajouterImageInfos("inconnue","MiniJeux/FrogLab/images/surprise.png",sz,sz)

        for joueur in joueurs:
            nom = joueur[0]
            self.cvs.ajouterTexte(nom,nom)

        self.imagesChargees = True

    def render(self):
        self.dessinerTimer()
        self.dessinerLabyrinthe()

        if not self.imagesChargees:
            self.chargerImagesElems(self.controleur.getJoueursInfos())

        listeImg=[]
        listeTxt=[]
        self.dessinerBiere(listeImg)
        self.dessinerSurprises(listeImg)
        self.dessinerJoueurs(listeImg,listeTxt)

        self.cvs.update(listeImg,listeTxt)

    # Fait la transformation de case logique a physique.
    def transPos(self,pos):
        x = pos[0] * self.largeurCases + self.largeurCases/2.0 + self.ox
        y = self.controleur.getHauteurLabyrinthe() - pos[1]
        y = y * self.largeurCases + self.largeurCases/2.0 - self.largeurCases + self.oy
        return x,y

    def dessinerJoueurs(self,listeImg,listeTxt):
        for joueur in self.controleur.getJoueursInfos():
            couleur=str(joueur[1])
            if self.controleur.estGele(joueur[0]):
                couleur = "gris"
            dir=str(self.controleur.mapDirection(joueur[2]))
            x,y = self.transPos([joueur[3].x, joueur[3].y])
            pos = Point(x,y)
            listeImg.append([couleur+"-"+dir, pos])

            # Dessiner le nom des joueurs:
            offset_x=self.largeurCases/2
            offset_y=self.largeurCases/2
            listeTxt.append([joueur[0],Point(pos.x-offset_x,pos.y-offset_y)])

    def dessinerEntree(self):
        entree = self.controleur.getEntree()
        x,y = self.transPos([entree.x,entree.y])
        self.canvas.create_rectangle(x-5,y-5,x+5,y+5,fill="purple")
        pass

    def dessinerBiere(self,liste):
        biere = self.controleur.getBiere()
        x,y = self.transPos([biere.x,biere.y])
        liste.append(["biere",Point(x,y)])

    def assignerItemsSurprises(self):
        imgs = {
                "deplacer"   : "deplacer-biere.png",
                "echanger"   : "echange.png",
                "geler"      : "sablier.png",
                "rapprocher" : "trounoir.png"
        }

        sz = int(self.largeurCases*0.75)

        for nom,s in surprises.items():
            self.imgSurprises = Img(imgs[nom],sz,sz)


    def dessinerSurprises(self,liste):
        surprises=self.controleur.getSurprises()

        for s in surprises:
            x,y = self.transPos([s[1].x, s[1].y])
            pos = Point(x,y)
            liste.append([s[0], pos])

    def quit(self,event):
        print("FrogLabVue::quit()")
        self.controleur.quit()
